package main

import (
	"log"
	"path/filepath"

	"hhchat.cn/yantool/util"

	"github.com/pkg/errors"
	"github.com/urfave/cli"
)

var (
	deployCmd = cli.Command{
		Name:  "d",
		Usage: "使用当前最新代码编译和运行",
		Flags: []cli.Flag{
			cli.BoolFlag{
				Name:  "compile, c",
				Usage: "是否编译新的 maven jar 包",
			},
			cli.StringFlag{
				Name:  "branch, m",
				Usage: "指定的分支",
				Value: "",
			},
			cli.BoolFlag{
				Name:  "update",
				Usage: "运行前，拉取最新代码并编译",
			},
			cli.StringSliceFlag{
				Name:  "projects",
				Usage: "所有关注的 pom 中登记的 project names",
			},
			cli.StringFlag{
				Name:  "version",
				Usage: "版本号",
				Value: "0.0.1-SNAPSHOT",
			},
			cli.StringFlag{
				Name:  "username, u",
				Value: "ubuntu",
				Usage: "用户名称",
			},
			cli.StringFlag{
				Name:   "home",
				Usage:  "用户文件夹目录",
				EnvVar: "HOME",
			},
			cli.StringFlag{
				Name:  "env",
				Usage: "运行的环境，test, dev, prod",
				Value: "test",
			},
			cli.BoolFlag{
				Name:  "verbose, v",
				Usage: "是否显示细节输出",
			},
		},
		Action: func(ctx *cli.Context) error {
			// 获取 flag
			needCompile := ctx.Bool("compile")
			branch := ctx.String("branch")
			update := ctx.Bool("update")
			projects := ctx.StringSlice("projects")
			version := ctx.String("version")
			detail := ctx.Bool("v")

			yanBackHome := filepath.Join("documents", "yan-back")
			home := ctx.String("home")
			env := ctx.String("env")

			log.Printf("当前环境 %s", env)

			// 是否是一个 git 仓库
			log.Printf("git 仓库检查...")
			isGit, err := util.GitIsRepository()
			if err != nil {
				log.Fatalf("Check git error: %s", err.Error())
				return err
			}
			if !isGit {
				err = errors.New("This is not a git repository, please check")
				log.Fatal(err.Error())
				return err
			}
			log.Printf("git 仓库检查通过")

			// 是否要跳转到指定分支, 清理当前变更
			if branch != "" {
				// 是否需要切换分支
				log.Printf("切换分支 %s...", branch)
				util.GitCheckoutBranch(branch, true, detail)
				log.Printf("分支切换完成")
			}

			// 是否要更新代码
			if update {
				// 拉取新代码
				log.Printf("最新代码拉取...")
				util.GitPull(true, true, detail)
				log.Printf("最新代码拉取完成")
			}

			// 确定是不是 mvn 项目
			log.Printf("maven 项目检查中...")

			isMvn, err := util.IsMvnProject()
			if err != nil {
				log.Fatalf("Check mvn error: %s", err.Error())
				return err
			}
			if !isMvn {
				err = errors.New("This is not a mvn project, please check")
				log.Fatalf(err.Error())
				return err
			}

			log.Printf("maven 项目检查通过")

			log.Printf("maven 清除历史数据...")
			util.MvnClean(detail)
			log.Printf("maven 历史数据清除完成")

			// 是否要编译
			if update || needCompile {
				log.Printf("正在编译代码...")
				err = util.MvnCleanPackageInstall(false, detail)
				if err != nil {
					log.Fatalf("编译出错: %s", err.Error())
					return err
				}
				log.Printf("编译代码完成")
			}

			if env == "prod" {
				util.RunShell(detail, "nginx", "-s", "stop")
				util.RunShell(detail, "mnginx")
			}

			log.Printf("停止服务...")
			err = util.RunShellWithDir(detail, filepath.Join(home, yanBackHome), "sh", "./stop.sh")
			log.Printf("停止服务完成")

			log.Printf("挪动 jar 包...")

			// 挪动代码到
			for _, project := range projects {
				fileName := project + "-" + version + ".jar"
				mvnPath := filepath.Join(".m2", "repository", "cn", "buaa", project, version)
				src := filepath.Join(home, mvnPath, fileName)
				dst := filepath.Join(home, yanBackHome, "")

				if detail {
					log.Printf("移动 jar [%s] to [%s]", src, dst)
				}

				err = util.RunShell(detail, "cp", src, dst)
				if err == nil {
					log.Printf("jar 包 %s 复制成功!", fileName)
				} else {
					log.Printf("复制 jar 包 %s 失败: %s", fileName, err.Error())
					return err
				}
			}

			util.MvnClean(detail)
			log.Printf("清理缓存文件完成")

			if env == "prod" {
				log.Printf("恢复 nginx")
				util.RunShell(detail, "nginx")
			}

			log.Printf("复制完成，正在启动...")
			err = util.RunShellWithDir(detail, filepath.Join(home, yanBackHome), "sh", "./start.sh")
			if err != nil {
				log.Fatalf("启动脚本执行出错: %s", err.Error())
			}
			log.Printf("启动脚本已经执行")

			return nil
		},
	}
	logCmd = cli.Command{
		Name:  "backlog",
		Usage: "查看后端输出日志",
		Flags: []cli.Flag{
			cli.StringFlag{
				Name:   "home",
				Usage:  "用户文件夹目录",
				EnvVar: "HOME",
			},
			cli.StringFlag{
				Name:  "env",
				Usage: "运行的环境，test, dev, prod",
				Value: "test",
			},
			cli.StringFlag{
				Name: "file",
				Usage: "日志文件",
				Value: "nohup.out",
			},
		},
		Action: func(ctx *cli.Context) error {
			home := ctx.String("home")
			yanBackHome := filepath.Join("documents", "yan-back")
			fileName := ctx.String("file")
			logFile := filepath.Join(home, yanBackHome, fileName)
			util.RunWithOutput("","tail", "-500f", logFile)
			return nil
		},
	}
)
